package br.unisinos.ubicomp.locationawaretaskmanager;

import java.util.ArrayList;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.Toast;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.MapView;
import com.google.android.maps.MyLocationOverlay;
import com.google.android.maps.OverlayItem;

public class MapOverlay extends ItemizedOverlay<OverlayItem> {
	private ArrayList<OverlayItem> mapOverlays = new ArrayList<OverlayItem>();
	
	private Drawable pin;
	private OverlayItem currentItem;
	private ImageView dragImage;
	private int xDragImageOffset = 0;
	private int yDragImageOffset = 0;
	private int xDragTouchOffset = 0;
	private int yDragTouchOffset = 0;
	private GeoPoint location;
	
	private Context context;
	

	public MapOverlay(Drawable defaultMarker) {
		super(defaultMarker);
		this.pin = defaultMarker;
	}

	public MapOverlay(Drawable defaultMarker, Context context, GeoPoint initialLocation) {
		this(defaultMarker);
		this.context = context;
		
		this.dragImage = (ImageView) ((TaskLocationMaps) this.context).findViewById(R.id.drag);
		this.xDragImageOffset = this.dragImage.getDrawable().getIntrinsicWidth()/2;
	    this.yDragImageOffset = this.dragImage.getDrawable().getIntrinsicHeight();
	    
	    GeoPoint startLocation;
	    if (initialLocation != null) {
	    	startLocation = initialLocation;
	    } else {
	    	startLocation = getCurrentLocation();
	    }
	    
	    this.location = startLocation;
	    
	    mapOverlays.add(new OverlayItem(startLocation, "", ""));
	    populate();
	}

	public GeoPoint getOverlayLocation() {
		return this.location;
	}
	
	private GeoPoint getCurrentLocation() {
		Location currentLocation = MainTaskManager.getCurrentLocation();
	    double latitude;
	    double longitude;
	    
	    if(currentLocation != null) {
	    	latitude = currentLocation.getLatitude();
	    	longitude = currentLocation.getLongitude();
	    } else {
	    	latitude = -29.79469730177113;
	    	longitude =  -51.15378141403198;
	    }
	    
	    return new GeoPoint((int) (latitude * 1E6),
			                (int) (longitude * 1E6) );
	}
	
	@Override
	protected OverlayItem createItem(int i) {
		return mapOverlays.get(i);
	}

	@Override
	public void draw(Canvas canvas, MapView mapView, boolean shadow) {
		super.draw(canvas, mapView, shadow);
		
		boundCenterBottom(pin);
	}
	
	@Override
	public int size() {
		return mapOverlays.size();
	}

	// @Override
	// protected boolean onTap(int index) {
	// OverlayItem item = mapOverlays.get(index);
	// AlertDialog.Builder dialog = new AlertDialog.Builder(context);
	// dialog.setTitle(item.getTitle());
	// dialog.setMessage(item.getSnippet());
	// dialog.show();
	// return true;
	// }

	@Override
	public boolean onTouchEvent(MotionEvent event, MapView mapView) {
		final int action = event.getAction();
		int X = (int) event.getX();
		int Y = (int) event.getY();
		boolean result = false;
		
		if (action == MotionEvent.ACTION_DOWN) {
			for (OverlayItem item : mapOverlays) {
				Point point = new Point(0,0);
				
				((TaskLocationMaps) this.context).getMapView().getProjection().toPixels(item.getPoint(), point);
				
				if(hitTest(item, pin, X - point.x, Y - point.y)) {
					result = true;
					
					this.currentItem = item;
					mapOverlays.remove(this.currentItem);
					populate();
					
					this.xDragTouchOffset = 0;
					this.yDragTouchOffset = 0;
					
					setDragImagePosition(point.x, point.y);
					this.dragImage.setVisibility(View.VISIBLE);
					
					this.xDragTouchOffset = X - point.x;
					this.yDragTouchOffset = Y - point.y;
					
					break;
				}
			}
		} else if (action == MotionEvent.ACTION_MOVE && currentItem != null) {
			setDragImagePosition(X,Y);
			result = true;
		} else if (action == MotionEvent.ACTION_UP && currentItem != null) {
			dragImage.setVisibility(View.GONE);
			
			GeoPoint geoPoint = ((TaskLocationMaps) this.context).getMapView().
								getProjection().fromPixels(X - this.xDragTouchOffset,
                                                           Y - this.yDragTouchOffset );

			OverlayItem overlayitem = new OverlayItem(geoPoint, 
					                                  currentItem.getTitle(), 
					                                  currentItem.getSnippet());

			Toast.makeText(this.context, 
					       geoPoint.getLatitudeE6()+" "+ geoPoint.getLongitudeE6(),
					       Toast.LENGTH_SHORT).show();
			
			mapOverlays.add(overlayitem);
			populate();
			
			((TaskLocationMaps) this.context).setSelectedPoint(this.currentItem.getPoint());

			currentItem = null;
			result = true;
		}

		return (result || super.onTouchEvent(event, mapView));
	}
	
	private void setDragImagePosition(int x, int y) {
		RelativeLayout.LayoutParams lp=
				(RelativeLayout.LayoutParams) dragImage.getLayoutParams();

		lp.setMargins(x - xDragImageOffset - xDragTouchOffset,
				y - yDragImageOffset - yDragTouchOffset, 0, 0);

		dragImage.setLayoutParams(lp);
	}

}
